import { AfterViewInit, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ApiService } from '@core/services/http/api.service';
import { ApesMessageService } from '@shared/apes/message';
import { Events } from '@core/services/events/Events';
import { Lodop, LodopService } from '@shared/apes/lodop';
import { getJson } from '../../../utils/utils';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { FormGroup } from '@angular/forms';
import { toNumber } from '@shared/apes/core/util/convert';
import { ExpressionService } from '@core/services/expression/ExpressionService';

@Component({
  selector: 'batch-printing-templates',
  templateUrl: './batch-printing-templates.component.html',
})
export class BatchPrintingTemplatesComponent implements OnInit, AfterViewInit {

  ctx = { model: {} };
  buttonBar = [
    // { hide: true, style: 'primary', label: '打印设计', id: 'action_design', loading: false },
    // { hide: true, style: 'primary', label: '打印预览', id: 'action_preview', loading: false },
    { hide: true, style: 'primary', label: '模版配置', id: 'action_formId', loading: false },
    { hide: true, style: 'primary', label: '模版数据', id: 'action_api', loading: false },
    { hide: true, style: 'primary', label: '模版设计', id: 'action_formPreview', loading: false },
  ];

  error = false;
  lodop: Lodop = null;
  value: any;

  form = new FormGroup({});
  model: any = {
    formId: 'print.template',
    formMetadata: '',
    api: 'purchase.order.findOne',
    id: '1000022',
    setData: null,
  };
  field: FormlyFieldConfig[] = [
    {
      key: 'formId',
      type: 'input',
      templateOptions: {
        label: 'formId',
        divCol: 8,
        placeholder: '输入对应xml配置formId',
      },
    },
    {
      key: 'api',
      type: 'input',
      templateOptions: {
        label: 'api',
        divCol: 8,
        placeholder: '输入对应查询api接口',
      },
    },
    {
      key: 'id',
      type: 'input',
      templateOptions: {
        label: 'id',
        divCol: 8,
        placeholder: '输入对应查询单号入参id',
      },
    },
  ];

  taskName: any = '';                          // 模版名称

  constructor(private apiService: ApiService,
              private msg: ApesMessageService,
              private cd: ChangeDetectorRef,
              protected events: Events,
              public lodopSrv: LodopService,
              protected expressionService: ExpressionService,
  ) {
    this.lodopSrv.lodop.subscribe(({ lodop, ok }) => {
      if (!ok) {
        this.error = true;
        return;
      }
      this.error = false;
      this.lodop = lodop;
    });
  }

  ngOnInit() {

  }

  ngAfterViewInit() {
  }

  onEvent(data) {
    if (data instanceof MouseEvent) return;
    if (data) {
      if (data.id === 'action_design') {
        // this.createPrintPage();
      } else if (data.id === 'action_preview') {
        // this.preview();
      } else if (data.id === 'action_formId') {
        this.getPrintTemplate();
      } else if (data.id === 'action_api') {
        this.getTemplateData();
      } else if (data.id === 'action_formPreview') {
        this.getTemplatePreview();
      }
    }
  }

  // createPrintPage() {
  //   let LODOP = this.lodop;
  //   LODOP.PRINT_INIT('套打EMS的模板');
  //   // tslint:disable-next-line:no-eval
  //   eval(this.value);
  //   if (LODOP.CVERSION) {
  //     LODOP.On_Return = (taskID, value) => {
  //       this.value = value;
  //     };
  //   }
  //   this.value = LODOP.PRINT_DESIGN();
  // };
  //
  // preview() {
  //   let LODOP = this.lodop;
  //   // tslint:disable-next-line:no-eval
  //   eval(this.value);
  //   if (LODOP.CVERSION) LODOP.On_Return = null;
  //   LODOP.PREVIEW();
  // }

  getPrintTemplate() {
    let formId = this.model.formId;
    this.apiService.post('form.get', { 'body': getJson({ id: formId }) }).subscribe(body => {
      console.log(body);
      this.model.formMetadata = body;
    });
  }

  getTemplateData() {
    let api = this.model.api;
    let id = this.model.id;
    this.apiService.post(api, { 'id': id }).subscribe(body => {
      console.log(body);
      this.model.setData = body;
    });
  }

  getTemplatePreview() {
    let formMetadata = this.model.formMetadata;
    let setData = this.model.setData;
    this.getConvertTemplate(formMetadata, setData);
  }

  getConvertTemplate(params, printData) {
    this.taskName = params.title;
    let sheet = params.sheet;
    let table = {};
    let header = {};
    let footer = {};
    let custom = {};
    if (sheet.length != 0) {
      sheet.forEach((st) => {
        if (st && st.renderData) {
          st.renderData.forEach((params) => {
            switch (params.type) {
              case 'header' :
                header = {
                  html: this.convertHtmlTemplate(params, printData),
                  options: params,
                };
                break;
              case 'table':
                table = {
                  html: this.convertTableTemplate(params, printData),
                  options: params,
                };
                break;
              case 'footer':
                footer = {
                  html: this.convertHtmlTemplate(params, printData),
                  options: params,
                };
                break;
              case 'custom':
                custom = {
                  list: this.convertCustomStructure(params),
                  printData: printData,
                };
                break;
            }
          });
        }
      });
    }
    this.addPrintTemplate(header, footer, table, custom);
  }

  convertHtmlTemplate(params, printData) {
    let trList = this.convertHtmlStructure(params);
    let textHtml = this.spliceMainHTML(trList, printData);
    console.log(textHtml);
    return textHtml;
  }

  convertTableTemplate(params, printData) {
    console.log('table', params);
    let trList = this.convertTableStructure(params);
    let id = params.title;
    let data = printData ? printData[id] : null;
    let textHtml = this.spliceTableHTML(trList, data);
    console.log(textHtml);
    return textHtml;
  }

  convertCustomStructure(params) {
    let fields = params.fields;
    let list = [];
    fields.forEach((data) => {
      let options = {
        key: data.key,
        label: data.label,
        widget: data.type,
        ...data.templateOptions,
      };
      list.push(options);
    });
    console.log(list);
    return list;
  }

  convertHtmlStructure(params) {
    let trList = [];
    params.fields.forEach((field) => {
      let options = {
        key: field.key,
        label: field.templateOptions.label,
        width: this.colToWidth(field.templateOptions.divCol),
        valueFormatter: field.templateOptions.valueFormatter,
        colspan: field.templateOptions.colspan
      };

      let tr = field.templateOptions.tr;
      let existingTr = trList.find((item) => item.tr === tr); // 查找是否已经存在对应的表格行

      if (existingTr) {
        existingTr.list.push(options); // 如果已存在对应表格行，则将选项添加到其 list 中
      } else {
        trList.push({ tr: tr, list: [options] }); // 如果不存在对应表格行，则添加新的表格行对象到 list 数组中
      }
    });
    console.log('转换数据--', trList);
    return trList;
  }

  convertTableStructure(params) {
    let trList = [];
    params.fields.forEach((field) => {
      let options = {
        key: field.key,
        label: field.templateOptions.label,
        width: this.colToWidth(field.templateOptions.divCol),
        valueFormatter: field.templateOptions.valueFormatter,
        textAlign: field.templateOptions.textAlign,
      };
      if (field.templateOptions.hasOwnProperty('sum')) {
        options['sum'] = true;
      }
      trList.push(options);
    });
    console.log('转换数据--', trList);
    return trList;
  }

  spliceMainHTML(trList, printData) {
    let textHtml = `<table border=0 cellSpacing=0 cellPadding=0 style="width: 100%;font-size: 15px; line-height: 20px;">\r\n<tbody>\r\n`;
    trList.forEach((tr) => {
      textHtml += `<tr>\r\n`;
      tr.list.forEach((td) => {
        let data = '';
        if (printData && printData[td.key]) {
          data = this.valueFormatter(td, printData);
        }
        let width = td.width;
        let colspan = td.colspan ? td.colspan : 0;
        textHtml +=
          `<td style="width: ${width}" colspan="${colspan}">${td.label} ${td.label ? ':' : ''}<span>${data}</span></td>\r\n`;
      });
      textHtml += `</tr>\r\n`;
    });
    textHtml += `</tbody>\r\n</table>`;
    return textHtml;
  }

  spliceTableHTML(trList, printData) {
    let textHtml = `<table border=1 cellSpacing=0 cellPadding=1 style="width: 100%;font-size: 14px;border-collapse:collapse;margin-bottom: 20px; line-height: 30px;" bordercolor="#333333">\r\n<thead>\r\n`;
    textHtml += `<tr>\r\n`;
    let sumList = [];
    trList.forEach((td) => {
      let width = td.width;
      textHtml += `<td style="width: ${width};text-align:center;">${td.label}</td>\r\n`;
      if (td.hasOwnProperty('sum')) {
        sumList.push({ key: td.key, sum: 0 });
      }
    });
    textHtml += `</tr>\r\n</thead>\r\n`;
    if (printData && printData.length != 0) {
      textHtml += `<tbody>\r\n`;
      printData.forEach((item) => {
        textHtml += `<tr>\r\n`;
        trList.forEach((td) => {
          let data = '';
          if (item && item[td.key]) {
            data = this.valueFormatter(td, item);
          }
          let width = td.width;
          let textAlign = td['textAlign'] ? td['textAlign'] : 'left';
          textHtml +=
            `<td style="width: ${width};text-align: ${textAlign}">${data}</td>\r\n`;
          sumList.forEach((list) => {
            if (list.key == td.key) {
              list.sum += data;
            }
          });
        });
        textHtml += `</tr>\r\n`;
      });
      textHtml += `</tbody>\r\n`;
    }

    console.log(sumList);

    if (sumList.length != 0) {
      textHtml += `<tfoot>\r\n`;
      trList.forEach((td) => {
        let width = td.width;
        let textAlign = td['textAlign'] ? td['textAlign'] : 'left';
        let data = '';
        sumList.forEach((list) => {
          if (list.key == td.key) {
            data = (list.sum).toFixed(2);
          }
        });
        textHtml +=
          `<td style="width: ${width};text-align: ${textAlign}">${data}</td>\r\n`;
      });
      textHtml += `</tfoot>\r\n`;
    }

    textHtml += `</table>`;
    return textHtml;
  }

  addPrintTemplate(header, footer, table, custom) {
    let LODOP = this.lodop;
    if (LODOP.CVERSION) {
      LODOP.On_Return = (taskID, value) => {
        this.value = value;
      };
    }
    LODOP.PRINT_INIT('套打EMS的模板');
    LODOP.SET_PRINT_PAGESIZE(1, 0, 0, 'A4');
    // LODOP.SET_PRINT_PAGESIZE(3, '2160', '930', 'A5');


    this.addHTM(LODOP, header);

    this.addTable(LODOP, table);

    this.addHTM(LODOP, footer);

    if (Object.keys(custom).length !== 0) {
      this.addCustom(LODOP, custom);
    }

    this.value = LODOP.PRINT_DESIGN();
    // this.value = LODOP.PREVIEW();
  }

  addHTM(LODOP, param) {
    let html = param.html;
    let options = param.options;

    LODOP.ADD_PRINT_HTM(options.top, options.left, options.width, options.height, html);
    LODOP.SET_PRINT_STYLEA(0, 'HOrient', 2);

    this.addStyle(LODOP, options);
  }

  addTable(LODOP, param) {
    let html = param.html;
    let options = param.options;
    LODOP.ADD_PRINT_TABLE(options.top, options.left, options.width, options.height, html);

    // 水平位置锁定方式：0 左边 1 右边 2 居中 3 中间拉伸
    LODOP.SET_PRINT_STYLEA(0, 'HOrient', 2);

    // 垂直位置 锁定方式：0 上边 1 下边 2 居中 3 中间拉伸
    LODOP.SET_PRINT_STYLEA(0, 'Vorient', 3);

    // this.addStyle(LODOP, options);
  }

  addCustom(LODOP, param) {
    console.log(param);
    let list = param.list;
    let printData = param.printData;
    list.forEach((li) => {
      this.addCustomTemplate(LODOP, li, printData);
    });
  }

  addCustomTemplate(LODOP, param, printData) {
    let widget = param.widget;
    switch (widget) {
      case 'barcode':
        this.addBarcode(LODOP, param, printData);
        break;
      case 'text':
        this.addText(LODOP, param, printData);
        break;
    }
  }

  // 条形码
  addBarcode(LODOP, param, printData) {
    let key = param.key;
    let value = printData[key];
    let type = param.type; // 条形码类型

    LODOP.ADD_PRINT_BARCODE(param.top, param.left, param.width, param.height, type, value);
  }

  // 纯文本
  addText(LODOP, param, printData) {
    let value = this.valueFormatter(param, printData);

    LODOP.ADD_PRINT_TEXT(param.top, param.left, param.width, param.height, value);

    this.addStyle(LODOP, param);

  }

  // 打印样式
  addStyle(LODOP, param) {

    // 字体：单位 px
    if (param.hasOwnProperty('fontSize')) {
      let fontSize = param.fontSize;
      LODOP.SET_PRINT_STYLEA(0, 'FontSize', fontSize);
    }

    // 字体颜色
    if (param.hasOwnProperty('fontColor')) {
      let fontColor = param.fontColor;
      LODOP.SET_PRINT_STYLEA(0, 'FontColor', fontColor);
    }

    // 字体粗体： 1 粗体 0 非粗
    if (param.hasOwnProperty('bold')) {
      let bold = param.bold;
      LODOP.SET_PRINT_STYLEA(0, 'Bold', bold);
    }

    // 基础属性：0 默认值 1 页眉页脚 2 页号 3 页数 4 多页项
    if (param.hasOwnProperty('itemType')) {
      let itemType = toNumber(param.itemType);
      LODOP.SET_PRINT_STYLEA(0, 'ItemType', itemType);
    }

    // 设置关联项：整数 按顺序关联1开始 负数 按前一个对象关联 -1
    if (param.hasOwnProperty('linkedItem')) {
      let linkedItem = toNumber(param.linkedItem);
      LODOP.SET_PRINT_STYLEA(0, 'LinkedItem', linkedItem);
    }
  }

  valueFormatter(param, printData) {
    let key = param.key;
    let value = printData ? printData[key] : '';
    if (param.hasOwnProperty('valueFormatter') && param.valueFormatter) {
      value = this.formatter(value, param.valueFormatter);
    }
    if (value == null) {
      value = '';
    }
    return value;
  }

  formatter(value: any, expression: string) {
    return this.expressionService.evaluate(expression, {
      value: value,
    });
  }

  colToWidth(col) {
    let width;
    width = ((100 / 24) * col).toFixed(2) + '%';
    return width;
  }

}

